<?php
namespace api\modules\collection\controllers;


use common\components\collection\Config;
use common\components\tools\FileHelper;
use common\components\tools\Model;
use common\models\CollectionTask;
use common\models\CollectionTemplate;
use wodrow\yii\rest\ApiException;
use wodrow\yii\rest\Controller;
use GuzzleHttp\Client;
use function GuzzleHttp\Psr7\str;

/**
 * Description of DefaultController
 *
 * @author wodrow
 */
class DefaultController extends Controller
{
    /**
     * 1. 获取模板列表
     * @desc get/post
     * @return array plat_resp 对接方响应
     * @return array templates 模板
     */
    public function actionGetTemplateList() 
    {
        $client = new Client([
            'base_uri' => Config::$base_uri,
        ]);
        $resp = $client->request('GET', '/callout-adapter/adapter/templates', [
            'headers' => [
                'clientId' => Config::$clientId,
                'clientSecret' => Config::$clientSecret,
                'grantType' => Config::$grantType,
            ],
        ]);
        $cont = $resp->getBody()->getContents();
        $_cont = json_decode($cont, true);
        if ($_cont['code'] != 0){
            throw new ApiException(201905130930, $_cont['message']);
        }
        $templates = [];
        foreach ($_cont['data'] as $k => $v) {
            $m = CollectionTemplate::findOne(['template_id' => $v['id']]);
            if (!$m){
                $m = new CollectionTemplate();
                $m->template_id = (string)$v['id'];
                $m->template_name = $v['name'];
                $m->get_at = $m->updated_at = time();
                $m->template_name = $v['name'];
                if (!$m->save()){
                    throw new ApiException(201905130931, Model::getModelError($m));
                }
            }
            if ($m->template_name != $v['name']){
                $m->template_name = $v['name'];
                if (!$m->save()){
                    throw new ApiException(201905130932, Model::getModelError($m));
                }
            }
            $templates[] = $m->toArray();
        }
        return [
            'plat_resp' => $_cont,
            'templates' => $templates,
        ];
    }

    /**
     * 获取声音包
     */
    public function actionVoicePackets()
    {
        $client = new Client([
            'base_uri' => Config::$base_uri,
        ]);
        $resp = $client->request('GET', '/callout-adapter/adapter/voice-packets', [
            'headers' => [
                'clientId' => Config::$clientId,
                'clientSecret' => Config::$clientSecret,
                'grantType' => Config::$grantType,
            ],
        ]);
        $cont = $resp->getBody()->getContents();
        $_cont = json_decode($cont, true);
        if ($_cont['code'] != 0){
            throw new ApiException(201905210919, $_cont['message']);
        }
        return [
            'plat_resp' => $_cont,
        ];
    }

    /**
     * (2)  任务创建
     * @desc get/post
     * @param string $json demo:{"name":"test201905101626","templateId":2000338,"threshold":2,"voiceType":"normal","phones":[{"phone":"17091551612","userData":{"key":"value"},"properties":{"动态字段1":{"text":"aaaa"},"动态字段2":{"text":"bbbb"}}}],"rules":[{"dayOfWeek":6,"startTime":"16:30","endTime":"18:00"}],"dynamicProperties":["动态字段1","动态字段2"],"calloutResultSyncUrl":"外呼结果回调url","ruleControl":{"redialTimes":0,"redialPeriod":24,"redialReason":["无法接通"]}}
     * @params String $name	任务名称，确保每次的创建的任务名称不相同
     * @params Integer $templateId	模板id
     * @params List $phones	号码列表
     * @params String $phone	号码
     * @params Object $properties	该号码动态字段
     * @params String $text	该动态字段对应的值
     * @params List $rules	任务的规则。  rules中,同一天内的时间段，必须做去重处理，如果有重复时间段，把数据合并
     * @params Integer $dayOfWeek	rules内日期在一周中的第几天，周日：1，周一：2.......
     * @params String $startTime	rules内规则开始时间
     * @params String $endTime	rules内规则结束时间
     * @params List $dynamicProperties	任务的动态字段
     * @params List $telQueue<String>	这个是PBX使用的，接入项目自己的PBX的人工队列是什么就设置什么。 队列1是#,1     队列15就是#,1,5
     * @params String $calloutResultSyncUrl	外呼结果回调第三方的url地址
     * @params Integer $threshold	机器人并发量
     * @params String $voiceType	外呼合成音类型，normal默认合成音，personality为个性化合成音。 默认使用normal默认合成音
     * @params Map $userData<String,Object>	用户需要的特殊透传字段，可以以k-v的形式存入
     * @params Object $ruleControl	规则控制，目前支持失败号码重播规则控制
     * @params Integer $redialTimes	重播次数，不填默认为0（不执行重播）
     * @params Integer $redialPeriod	重播间隔，默认24，单位小时
     * @params List $redialReason<String>	呼叫失败原因，例如：无法接通、关机、不在服务区、正在通话、无人接听、无法判断；针对外呼失败原因的号码，触发重播。不填，会默认使用以上6种原因
     * @return array task 任务
     * @return array plat_resp 对接方响应
     * @throws ApiException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \yii\base\Exception
     */
    public function actionAddTask($json)
    {
        $arr = json_decode($json, true);
        if (!isset($arr['name'])){
            $arr['name'] = "collectiontask_".date("YmdHis");
        }
        $template = CollectionTemplate::findOne(['template_id' => $arr['templateId']]);
        $task = CollectionTask::findOne(['task_name' => $arr['name']]);
        if ($task){
            throw new ApiException(201905131023, "任务{$arr['name']}已存在");
        }
        $task = new CollectionTask();
        $client = new Client([
            'base_uri' => Config::$base_uri,
        ]);
        $resp = $client->request('POST', '/callout-adapter/adapter/tasks', [
            'headers' => [
                'clientId' => Config::$clientId,
                'clientSecret' => Config::$clientSecret,
                'grantType' => Config::$grantType,
                'Content-Type' => 'application/json',
            ],
            'body' => $json,
        ]);
        $cont = $resp->getBody()->getContents();
        $_cont = json_decode($cont, true);
        if ($_cont['code'] != 0){
            throw new ApiException(201905131007, $_cont['message']);
        }
        $task->template_id = $template->id;
        $task->task_name = $arr['name'];
        $task->task_status = CollectionTask::TASK_STATUS_RESUME;
        $task->created_at = $task->updated_at = time();
        $task->req_json = $json;
        $task->task_id = $_cont['data'];
        if (CollectionTask::findOne(['task_id' => $_cont['data']])){
            throw new ApiException(201905131024, "任务{$_cont['data']}已存在");
        }
        if (!$task->save()){
            throw new ApiException(201905131030, Model::getModelError($task));
        }
        $task->req_json = $arr;
        return [
            'plat_resp' => $_cont,
            'task' => $task->toArray(),
        ];
    }

    /**
     * (3)  任务暂停继续
     * @desc get/post
     * @param string $task_id 任务id
     * @param string $task_status 任务状态#暂停：stop 继续：resume 终止：cancel
     * @return array task 任务
     * @return array plat_resp 对接方响应
     * @throws ApiException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \yii\base\Exception
     */
    public function actionTaskStatus($task_id, $task_status = 'resume')
    {
        $task = CollectionTask::findOne(['task_id' => $task_id]);
        if (!$task){
            throw new ApiException(201905131025, "任务{$task_id}不存在");
        }
        $json = <<<JSON
{
    "type": "{$task_status}"
}
JSON;
        $client = new Client([
            'base_uri' => Config::$base_uri,
        ]);
        $resp = $client->request('POST', "/callout-adapter/adapter/tasks/status/{$task_id}", [
            'headers' => [
                'clientId' => Config::$clientId,
                'clientSecret' => Config::$clientSecret,
                'grantType' => Config::$grantType,
                'Content-Type' => 'application/json',
            ],
            'body' => $json,
        ]);
        $cont = $resp->getBody()->getContents();
        $_cont = json_decode($cont, true);
        if ($_cont['code'] != 0){
            throw new ApiException(201905131007, $_cont['message']);
        }
        $task->task_status = $task_status;
        if (!$task->save()){
            throw new ApiException(201905131031, Model::getModelError($task));
        }
        $task->req_json = json_decode($task->req_json, true);
        return [
            'plat_resp' => $_cont,
            'task' => $task->toArray(),
        ];
    }

    /**
     * (5) 下载通话录音
     * @desc 描述：根据外呼结果中通话录音路径fdsfPath下载通话录音
     * @param string $fdsfPath 通话录音路径
     * @throws ApiException
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \yii\base\Exception
     */
    public function actionDownloadCallRecord($fdsfPath, $fileName = null)
    {
        $client = new Client([
            'base_uri' => Config::$base_uri,
        ]);
        $query = [
            'fdfsPath' => $fdsfPath,
        ];
        if ($fileName){
            $query['fileName'] = $fileName;
        }else{
            $query['fileName'] = basename($fdsfPath);
        }
        $sink = \Yii::getAlias('@uploads_root/collection_voice/'.$query['fileName']);
        if (!is_dir(dirname($sink))){
            FileHelper::createDirectory(dirname($sink));
        }
        $resp = $client->request('GET', '/callout-adapter/adapter/tasks/voices/download', [
            'headers' => [
                'clientId' => Config::$clientId,
                'clientSecret' => Config::$clientSecret,
                'grantType' => Config::$grantType,
            ],
            'query' => $query,
            'sink' => $sink,
        ]);
        $cont = $resp->getBody()->getContents();
        $_cont = json_decode($cont, true);
        if ($_cont['code'] != 0){
            throw new ApiException(201905130930, $_cont['message']);
        }
        return [
            'plat_resp' => $_cont,
        ];
    }
}
